package com.douyang.utils;


import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.douyang.base.model.PageResult;
import com.douyang.dto.VideoInfoListDTO;
import com.douyang.pojo.VideoBaseInfo;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.xcontent.XContentType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;

@Component
public class ESUtils {
    @Autowired
    private RestHighLevelClient client;


    public Page<VideoBaseInfo> selectByVideoInfoDTO(VideoInfoListDTO videoInfoListDTO,Boolean showDeleted) throws IOException {
        SearchRequest searchRequest = new SearchRequest("video_base_info");
        searchRequest.source()
                .query(QueryBuilders.termQuery("deleted", showDeleted))
                .from(Math.toIntExact(videoInfoListDTO.getPageNo()-1))
                .size(Math.toIntExact(videoInfoListDTO.getPageSize()));
        if(videoInfoListDTO.getAuthorId()!=null){
            searchRequest.source().query(QueryBuilders.termQuery("authorId", videoInfoListDTO.getAuthorId()));
        }
        if(StringUtils.isNotEmpty(videoInfoListDTO.getTitle())){
            searchRequest.source().query(QueryBuilders.matchQuery("title", videoInfoListDTO.getTitle()));
            searchRequest.source().highlighter(SearchSourceBuilder.highlight()
                    .field("title")
                    .preTags("<b>")
                    .postTags("</b>")
            );
        }
        if(StringUtils.isNotEmpty(videoInfoListDTO.getType())){
            searchRequest.source().query(QueryBuilders.matchQuery("typeName", videoInfoListDTO.getType()));
        }
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        SearchHit[] hits = searchResponse.getHits().getHits();
        if(hits==null || hits.length==0){
            Page<VideoBaseInfo>page=new Page<>();
            page.setRecords(List.of());
            page.setTotal(0);
            return page;
        }
        List<VideoBaseInfo> videoBaseInfoList = Arrays.stream(hits).map(hit -> {
            String json = hit.getSourceAsString();
            VideoBaseInfo bean = JSONUtil.toBean(json, VideoBaseInfo.class);
            if(StringUtils.isNotEmpty(videoInfoListDTO.getTitle()))bean.setTitle(hit.getHighlightFields().get("title").getFragments()[0].toString());
            return bean;
        }).toList();


        Page<VideoBaseInfo>page=new Page<>();
        page.setRecords(videoBaseInfoList);
        page.setTotal(searchResponse.getTotalShards());
        return page;
    }

    public void updateVideoBase(VideoBaseInfo videoBaseInfo) throws IOException {
        UpdateRequest updateRequest = new UpdateRequest();
        updateRequest
                .index("video_base_info")
                .id(videoBaseInfo.getId().toString())
                .doc(JSONUtil.toJsonStr(videoBaseInfo), XContentType.JSON);
        client.update(updateRequest, RequestOptions.DEFAULT);

    }

    public void insertVideoBase(VideoBaseInfo videoBaseInfo) throws IOException {
        IndexRequest indexRequest = new IndexRequest("video_base_info");
        indexRequest.id(videoBaseInfo.getId().toString())
                .source(JSONUtil.toJsonStr(videoBaseInfo),XContentType.JSON);
        client.index(indexRequest,RequestOptions.DEFAULT);
    }

    public void deleteVideoBaseById(Long id) throws IOException {
        DeleteRequest deleteRequest = new DeleteRequest("video_base_info",id.toString());
        client.delete(deleteRequest,RequestOptions.DEFAULT);
    }

    public void insertVideoBaseList(List<VideoBaseInfo> videoBaseInfoList) throws IOException {
        BulkRequest bulkRequest = new BulkRequest();
        videoBaseInfoList.forEach(v->
                bulkRequest.add(new IndexRequest("video_base_info").id(v.getId().toString()).source(JSONUtil.toJsonStr(v), XContentType.JSON)
        ));
        try {
            client.bulk(bulkRequest,RequestOptions.DEFAULT);
        }catch (Exception e){
            throw new IOException(e);
        }

    }
}
